#include <stdio.h>
#include <pthread.h>
#include <ctype.h>
#include "wrap.h"
//自定义数据结构
typedef struct _SockInfo{
        struct sockaddr_in addr;
        socklen_t addrLen;
        pthread_t tid;
        int cfd; //文件描述符
}SockInfo;
void* recyle(void* arg)
{
        char buf[1024] = {0};
        SockInfo* info = (SockInfo *)arg;
        while (1){
                printAddr("client ", &info->addr);
                int len = Read(info->cfd,buf,sizeof(buf));
                if(len == -1){
                        perror("read error");
                        pthread_exit(NULL);
                }else if(len == 0){
                        printAddr("客户端已经断开连接",&info->addr);
                        Close(info->cfd);
                        break;
                }else{
                        printf("recv buf %s\n",buf);
                        for (int i = 0; i < len; i++){
                                buf[i] = toupper(buf[i]);
                        }
                        Write(info->cfd,buf,len);
                }
        }
        return NULL;
}
int main(int argc, char const *argv[])
{
        int lfd = Socket(AF_INET,SOCK_STREAM,0);
        struct sockaddr_in serverAddr;
        serverAddr.sin_family = AF_INET;
        serverAddr.sin_port = htons(6666);
        serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);
        Bind(lfd, (struct sockaddr*)&serverAddr,sizeof(serverAddr));
        Listen(lfd, 128);
        printf("start accept ......\n");

        int i = 0;
        SockInfo info[256];
        for (i = 0; i < sizeof(info)/sizeof(info[0]); ++i){
                info[i].cfd = -1;
        }

        pthread_attr_t attr;
        pthread_attr_init(&attr);
        pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);

        while (1){
                //选择一个没有被使用的,最小的数组元素
                for (i = 0; i < 256; i++){
                        if(info[i].cfd == -1){
                                break;
                        }       
                }
                if(i == 256){
                        break;
                }
                info[i].addrLen = sizeof(info[i].addr);
                info[i].cfd = Accept(lfd,(struct sockaddr *)&info[i].addr, &info[i].addrLen);
                pthread_create(&info[i].tid,&attr,recyle,&info[i]);
        }
        pthread_attr_destroy(&attr);
        Close(lfd);
        pthread_exit(NULL);
        return 0;
}
